<?php

/*
 * $Id: base.php 12 2010-11-28 20:02:53Z LEON $
 * $Author: LEON $
 * $LastChangedDate: 2010-11-28 20:02:53 +0000 (Sun, 28 Nov 2010) $
 * $Revision: 12 $
 */

namespace cmFly\system\data_model\orm;

abstract class base {

    private static $tables;
    private static $used_relations;
    protected static $load_flags;
    protected static $status;
    protected $relations;

    protected function __construct() {
	
    }

    /**
     *
     * @return table
     */
    public static function get_table() {
	$namespace = \dirname(\get_called_class());
	if (!isset(self::$tables[$namespace])) {
	    $table_class = $namespace . '\\table';
	    self::$tables[$namespace] = new $table_class();
	}
	return self::$tables[$namespace];
    }

    /**
     *
     * @param string $without
     * @param string $without2 etc
     * @return \cmFly\db\sql_constructors\select
     */
    protected static function get_select($without=Array(),$with=Array()) {
	$called_class = \get_called_class();
	$table  = static::get_table();
	$select = $table->get_database()->get_constructor('select');
	$select->set_user_data(static::get_model_name());
	$select->from($table->get_name());
	$fields = $table->get_fields();
	$select->fields($fields);
	//Фильтрация закольцованных связей.
	$root_flag = false;

	if (!count(self::$used_relations)) {
	    $root_flag = true;
	}
	$model_name = \dirname($called_class);
	$namespace = \dirname($model_name);
	self::$used_relations[$model_name] = true;

	//Joins build
	$relations = $table->get_relations();
	foreach ($relations as $k => $v) {
	    /**
	     * @todo реализовать нормальную сборку связей
	     */
	    $relation_namespace = $namespace . '\\' . $v[$table::RELATION_CLASS];
	    //Если эта связь 1к1 с типом не отложенной загрузки
	    if ($v[$table::RELATION_TYPE] != $table::RELATION_ONE_TO_ONE
		    || ((isset($v[$table::LAZY]) && $v[$table::LAZY]) && \array_search($k, $with)===FALSE)
		    || isset(self::$used_relations[$relation_namespace])) {
		continue;
	    }
	    $class = $relation_namespace . '\\model';
	    $join = $class::get_related($v[$table::RELATION_CLASS_RELATION], Array($select->field($v[$table::RELATION_FIELD])));
	    $select->join($join);
	}
	if ($root_flag) {
	    self::$used_relations = Array();
	}
	return $select;
    }
    
    protected static function get_related($relation_name, array $fields) {
	$table = static::get_table();
	$relations = $table->get_relations();

	if (!isset($relations[$relation_name])) {
	    throw new \cmFly\data_model\exception('Not found relation name for "' . \get_called_class() . '"');
	}
	$current_relation = &$relations[$relation_name];

	$r = static::get_select($relation_name);
	$r->set_user_data(static::get_model_name());
	$r->where($current_relation[$table::RELATION_FIELD] . '=?', $fields);
	return $r;
    }

    protected static function build_related($relation_class, $relation_name, $vars) {
	$class = new static();
	$my_relation = &$class->relations[$relation_name];
	$my_relation['model'] = $relation_class;
	$class->data = $relation_class;
	return $class;
    }
  
    public static function get_model_name() {
	return dirname(\get_called_class());
    }

    public static function get_database($to='default') {
	return static::get_table()->get_database($to);
    }

}